package com.icinfo.cloud.provider.punish.common.datareport.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.icinfo.cloud.provider.common.constant.Constant;
import com.icinfo.cloud.provider.common.enums.TerritoryCodeEnum;
import com.icinfo.cloud.provider.common.enums.YesOrNoEnum;
import com.icinfo.cloud.provider.common.exception.BusinessException;
import com.icinfo.cloud.provider.common.utils.BaseUtil;
import com.icinfo.cloud.provider.common.utils.SpringContextUtil;
import com.icinfo.cloud.provider.punish.common.datareport.dto.CaseDataReportRecordQueryDto;
import com.icinfo.cloud.provider.punish.common.datareport.dto.CaseDataReportRequestCommonDto;
import com.icinfo.cloud.provider.punish.common.datareport.dto.CaseDataReportStageInfoQueryDto;
import com.icinfo.cloud.provider.punish.common.datareport.enums.CaseDataReportOptTypeEnum;
import com.icinfo.cloud.provider.punish.common.datareport.enums.CertTypeDataReportEnum;
import com.icinfo.cloud.provider.punish.common.datareport.enums.ReportDataTypeEnum;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportRecordService;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportService;
import com.icinfo.cloud.provider.punish.common.datareport.service.ICaseDataReportStageInfoService;
import com.icinfo.cloud.provider.punish.common.datareport.vo.CaseDataReportRecordVo;
import com.icinfo.cloud.provider.punish.common.datareport.vo.CaseDataReportStageInfoVo;
import com.icinfo.cloud.provider.punish.config.service.ISysDepartParamService;
import com.icinfo.cloud.provider.punish.csource.manage.enums.CaseSourceEnum;
import com.icinfo.cloud.provider.punish.csource.manage.model.CaseSourceRegisterDetailInfo;
import com.icinfo.cloud.provider.punish.csource.manage.service.ICaseSourceRegisterDetailInfoService;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CasePartiesRecordQueryDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.dto.CaseReasonMainRecordQueryDto;
import com.icinfo.cloud.provider.punish.ucase.casemain.enums.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseMainDetailInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.model.CaseMainDetailSimpleInfo;
import com.icinfo.cloud.provider.punish.ucase.casemain.service.*;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseHandlePersonRecordVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseMainInfoVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CasePartiesInfoVo;
import com.icinfo.cloud.provider.punish.ucase.casemain.vo.CaseReasonMainRecordVo;
import com.icinfo.cloud.provider.punish.ucase.caseregister.dto.CaseEmergencyReasonInfoDto;
import com.icinfo.cloud.provider.punish.ucase.caseregister.dto.PersonReasonIds;
import com.icinfo.framework.common.web.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 描述：案件数据上报接口实现类-基础信息
 *
 * @author xiangyuyu
 * @date 2022/6/13 17:36
 */
@Service
@Slf4j
public class CaseDataReportBasicServiceImpl implements ICaseDataReportService {

    private static final String TERRITORY_CODE_PREFIX = "001";
    /**
     * 行政基础信息推送接口
     */
    private static final String BASE_HTTP = "E5BeGhl3e4jPUbd8.htm";
    @Resource
    private ICaseMainDetailInfoService caseMainDetailInfoService;
    @Resource
    private ICasePartiesRecordService casePartiesRecordService;
    @Resource
    private ICaseHandlePersonRecordService caseHandlePersonRecordService;
    @Resource
    private ICaseReasonMainRecordService caseReasonMainRecordService;
    @Resource
    private ICaseMainInfoService caseMainInfoService;
    @Resource
    private ICaseDataReportStageInfoService caseDataReportStageInfoService;
    @Resource
    private ICaseDataReportRecordService caseDataReportRecordService;
    @Resource
    private ICaseMainDetailSimpleInfoService caseMainDetailSimpleInfoService ;
    @Resource
    private ICaseSourceRegisterDetailInfoService caseSourceRegisterDetailInfoService;
    @Resource
    private ISysDepartParamService sysDepartParamService;


    /**
     * 描述：批量案件数据上报
     * @param baseInfoReportFailCaseIdList 上报失败的案件id列表
     * @return {@link Result <String>} 上报失败案件id列表
     * @author xiangyuyu
     * @date 2022-06-13 18:52
     */
    @Override
    public List<String> batchCaseReport(List<String> baseInfoReportFailCaseIdList) {
        LocalDateTime startTime = LocalDateTime.now();
        log.info("basicInfoReport start-startTime:{}", startTime);
        if(ObjectUtils.isEmpty(baseInfoReportFailCaseIdList)){
            baseInfoReportFailCaseIdList = new ArrayList<>();
        }
        //查看2天前是否存在"立案审批表审批通过"的案件（排除多当事人）
        List<String> shouldUploadBasicInfo = caseMainDetailInfoService.getCaseIdListShouldReportBasicInfo();
        if (!ObjectUtils.isEmpty(shouldUploadBasicInfo) && shouldUploadBasicInfo.size() > 0) {
            //数据上报
            this.reportBasicInfoData(shouldUploadBasicInfo, baseInfoReportFailCaseIdList);
        } else {
            log.info("date:{},无立案审批表审批通过案件", startTime);
        }

        LocalDateTime endTime = LocalDateTime.now();
        Duration duration = Duration.between(startTime, endTime);
        long seconds = duration.getSeconds();
        log.info("basicInfoReport end-endTime:{},consume:{} s", endTime, seconds);
        return baseInfoReportFailCaseIdList;
    }

    /**
     * 描述：批量案件数据上报
     * @param baseInfoReportFailCaseIdList 上报失败的案件id列表
     * @param punishDecideCaseIdList 处罚决定的案件ID列表
     * @return {@link Result <String>} 上报失败案件id列表
     * @author mahan
     * @date 2022-10-20 18:52
     */
    public List<String> batchCaseReport(List<String> baseInfoReportFailCaseIdList, List<String> punishDecideCaseIdList) {
        LocalDateTime startTime = LocalDateTime.now();
        log.info("basicInfoReport start-startTime:{}", startTime);
        if(ObjectUtils.isEmpty(baseInfoReportFailCaseIdList)){
            baseInfoReportFailCaseIdList = new ArrayList<>();
        }
        //查看2天前是否存在"立案审批表审批通过"的案件（排除多当事人）
        List<String> shouldUploadBasicInfo = caseMainDetailInfoService.getCaseIdListShouldReportBasicInfo(punishDecideCaseIdList);
        if (!ObjectUtils.isEmpty(shouldUploadBasicInfo) && shouldUploadBasicInfo.size() > 0) {
            //数据上报
            this.reportBasicInfoData(shouldUploadBasicInfo, baseInfoReportFailCaseIdList);
        } else {
            log.info("date:{},无立案审批表审批通过案件", startTime);
        }

        LocalDateTime endTime = LocalDateTime.now();
        Duration duration = Duration.between(startTime, endTime);
        long seconds = duration.getSeconds();
        log.info("basicInfoReport end-endTime:{},consume:{} s", endTime, seconds);
        return baseInfoReportFailCaseIdList;
    }

    /**
     * 数据上报
     * @param shouldUploadBasicInfo
     * @param baseInfoReportFailCaseIdList
     */
    private void reportBasicInfoData(List<String> shouldUploadBasicInfo, List<String> baseInfoReportFailCaseIdList){
        log.info("立案审批表审批通过案件数量:{}", shouldUploadBasicInfo.size());
        List<String> finalBaseInfoReportFailCaseIdList = baseInfoReportFailCaseIdList;
        shouldUploadBasicInfo.forEach(e -> {
            if (!finalBaseInfoReportFailCaseIdList.contains(e)) {
                CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(e);
                if (!caseDataReportRecordService.personalCheckIsAllowDataReport(e, caseMainInfo)) {
                    return;
                }
                if(TerritoryCodeEnum.RLSB.getCode().equals(caseMainInfo.getCaseTerritoryCode())){
                    return;
                }
                String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
                String handleType = caseMainInfo.getHandleType();
                CasePartiesRecordQueryDto queryDto = new CasePartiesRecordQueryDto(e,null,YesOrNoEnum.NO.getCode());
                List<CasePartiesInfoVo> partiesInfo = casePartiesRecordService.getCasePartiesInfoList(queryDto);
                if (!(PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)
                        && HandleTypeEnum.PART_PUNISH.getCode().equals(handleType))
                ) {
                    //只取第一个当事人信息
                    List<CasePartiesInfoVo> tmp = new ArrayList<>();
                    tmp.add(partiesInfo.get(Constant.INTEGER_0));
                    partiesInfo = tmp;
                    partiesInfo.forEach(p->p.setPartyId(null));
                }
                CaseDataReportRequestCommonDto dto = new CaseDataReportRequestCommonDto();
                dto.setCaseId(e);
                for (CasePartiesInfoVo partyInfo : partiesInfo) {
                    String partyId = partyInfo.getPartyId();
                    //初始化数据上报阶段信息
                    caseDataReportStageInfoService.initCaseReportStageInfo(e,partyId);
                    //校验是否需要上报
                    boolean isShouldReport = caseDataReportStageInfoService.checkIsShouldReport(ReportDataTypeEnum.BASE.getCode(), e,partyId);
                    if (isShouldReport) {
                        Result<String> result = singleCaseReport(dto,partyInfo,caseMainInfo);
                        if (!caseDataReportRecordService.analyseResultToJudgeIsReportSuccess(result)) {
                            finalBaseInfoReportFailCaseIdList.add(e);
                        }
                    }
                }
            }
        });
    }


    /**
     * 描述：单个案件数据上报
     *
     * @param dto          {@link CaseDataReportRequestCommonDto}
     * @param partyInfo    {@link CasePartiesInfoVo} 当事人信息
     * @param caseMainInfo {@link CaseMainInfoVo} 案件主体信息
     * @return {@link Result <String>} 上报结果
     * @author xiangyuyu
     * @date 2022-06-13 18:52
     */
    @Override
    public Result<String> singleCaseReport(CaseDataReportRequestCommonDto dto, CasePartiesInfoVo partyInfo, CaseMainInfoVo caseMainInfo) {
        log.info("dataReportBase start... dto:{}", dto);
        String caseId = dto.getCaseId();
        String optType = dto.getOptType();
        if(!ObjectUtils.isEmpty(optType)){
            if(!CaseDataReportOptTypeEnum.isLegalEnumCode(optType)){
                throw new BusinessException("请指定有效的数据上报更新类型枚举(I：新增， U：修改； D：删除)");
            }
        }
        if (!caseDataReportRecordService.personalCheckIsAllowDataReport(caseId, null)) {
            log.info("该案件暂不开启数据上报-caseId:{}", caseId);
            return Result.error("该案件暂不开启数据上报-caseId:" + caseId);
        }
        List<CasePartiesInfoVo> partiesInfo = new ArrayList<>();
        if (ObjectUtils.isEmpty(partyInfo)) {
            //获取当事人信息
            if (ObjectUtils.isEmpty(caseMainInfo)) {
                caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
            }
            String casePartiesReasonType = caseMainInfo.getCasePartiesReasonType();
            String handleType = caseMainInfo.getHandleType();
            CasePartiesRecordQueryDto queryDto = new CasePartiesRecordQueryDto(caseId, null, YesOrNoEnum.NO.getCode());
            partiesInfo = casePartiesRecordService.getCasePartiesInfoList(queryDto);
            if (!(PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)
                    && HandleTypeEnum.PART_PUNISH.getCode().equals(handleType))
            ) {
                //只取第一个当事人信息
                List<CasePartiesInfoVo> tmp = new ArrayList<>();
                tmp.add(partiesInfo.get(Constant.INTEGER_0));
                partiesInfo = tmp;
                partiesInfo.forEach(p -> p.setPartyId(null));
            }
        } else {
            partiesInfo.add(partyInfo);
        }

        for (CasePartiesInfoVo p : partiesInfo) {
            String partyId = p.getPartyId();
            try {
                //if (caseDataReportRecordService.getIsAllowDataReport(caseId)) {
                    String errorMsg = "";
                    //根据案件id查询案件信息
                    if (ObjectUtils.isEmpty(caseMainInfo)) {
                        caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
                    }
                    String uri = BASE_HTTP;
                    String reportDataType = ReportDataTypeEnum.BASE.getCode();
                    JSONObject reportData = reportDataCollect(caseMainInfo, reportDataType, false, p, optType);
                    Map<String, String> params = new HashMap<>(2);
                    params.put("reportActionType", !ObjectUtils.isEmpty(optType)?optType:reportData.getString("reportActionType"));
                    params.put("envFlag", reportData.getString("envFlag"));
                    params.put("baseInfo", reportData.toJSONString());
                    errorMsg = caseDataReportRecordService.dataReport(uri, reportDataType, params, caseMainInfo);

                    log.info("dataReportBase end");
                    if (ObjectUtils.isEmpty(errorMsg)) {
                        caseDataReportStageInfoService.dealAfterReport(caseId, true, ReportDataTypeEnum.BASE.getCode(), null, partyId);
                    } else {
                        if (errorMsg.contains(Constant.STRING_RECORD_EXISTS)) {
                            caseDataReportStageInfoService.dealAfterReport(caseId, true, ReportDataTypeEnum.BASE.getCode(), errorMsg, partyId);
                        } else if(errorMsg.contains(Constant.STRING_ERROR_SIGN)) {
                            caseDataReportRecordService.reportAgain(dto, partyInfo, caseMainInfo, this, reportDataType);
                        } else {
                            caseDataReportStageInfoService.dealAfterReport(caseId, false, ReportDataTypeEnum.BASE.getCode(), errorMsg, partyId);
                        }
                        return Result.error(errorMsg);
                    }
                /*} else {
                    String tmpMsg = "该部门是否允许上报数据按钮处于关闭状态,caseId:" + caseId;
                    throw new BusinessException(tmpMsg);
                }*/
            } catch (Exception e) {
                e.printStackTrace();
                caseDataReportStageInfoService.dealAfterReport(caseId, false, ReportDataTypeEnum.BASE.getCode(), e.getMessage(), partyId);
                return Result.error("dataReportBase catch exception：" + e.getMessage());
            }
        }
        return Result.success("上报成功");
    }


    /**
     * 描述：收集数据上报-案件基础信息
     *
     * @param caseMainInfoVo   {@link CaseMainInfoVo}
     * @param reportDataType   上报数据类型
     * @param isUpdateReReport 是否更新补推
     * @param partyInfo        {@link CasePartiesInfoVo} 当事人信息
     * @param partyInfo        {@link CasePartiesInfoVo} 当事人信息
     * @param optType          更新类型
     * @return {@link JSONObject} 上报数据内容
     * @author xiangyuyu
     * @date 2022-03-30 21:39
     */
    @Override
    public JSONObject reportDataCollect(CaseMainInfoVo caseMainInfoVo, String reportDataType, boolean isUpdateReReport,CasePartiesInfoVo partyInfo,String optType) {
        log.info("reportDataCollect start...param-caseMainInfoVo:{},reportDataType:{}", caseMainInfoVo, reportDataType);
        JSONObject returnInfo = new JSONObject();
        JSONObject baseInfo = new JSONObject();
        String caseId = caseMainInfoVo.getId();
        String caseNumber = caseMainInfoVo.getCaseNumber();
        String caseType = caseMainInfoVo.getCaseType();
        CaseMainDetailInfo caseMainDetailInfo;
        if(CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseType)){
            //简易处罚
            caseMainDetailInfo = new CaseMainDetailInfo();
            CaseMainDetailSimpleInfo caseMainDetailSimpleInfo = caseMainDetailSimpleInfoService.getCaseMainDetailSimpleInfo(caseId);
            if(ObjectUtils.isEmpty(caseMainDetailSimpleInfo)){
                throw new BusinessException("未匹配到简易处罚的案件详情信息-caseId:"+caseId);
            }
            caseMainDetailInfo.setCaseReason(caseMainDetailSimpleInfo.getCaseReason());
            caseMainDetailInfo.setCaseHappenTime(caseMainDetailSimpleInfo.getCaseHappenTime());
            caseMainDetailInfo.setIsIndustrialTradeSpecial(caseMainDetailSimpleInfo.getIsIndustrialTradeSpecial());
            //简易处罚的案件简介用违法事实填充
            caseMainDetailInfo.setCaseConciseCondition(caseMainDetailSimpleInfo.getIllegalFact());
            //简易处罚数据上报时案件编码用对应处罚决定书文号赋值
            caseNumber = caseMainDetailSimpleInfo.getPunishDocumentNumber();
        } else {
            //TODO：目前暂时将简易处罚之外的案件的宽表数据认为存储在case_main_detail_info,后期如果有新增宽表，得特殊处理
            caseMainDetailInfo = caseMainDetailInfoService.getCaseMainDetailByCaseId(caseId);
        }
        String caseReason = caseMainDetailInfo.getCaseReason();
        LocalDateTime caseHappenTime = caseMainDetailInfo.getCaseHappenTime();
        LocalDateTime registerTime = caseMainInfoVo.getCaseRegistTime();
        String caseTerritoryCode = caseMainInfoVo.getCaseTerritoryCode();
        String sourceDeptCode = TERRITORY_CODE_PREFIX + caseTerritoryCode;
        String orgCode = caseMainInfoVo.getCaseOrgCode();
        String areaCode = Constant.STRING_HORIZONTAL_BARS;
        //优先取member库表中配置的区划编码，如果取不到，截取orgCode
        if (ObjectUtils.isEmpty(orgCode)) {
            orgCode = Constant.STRING_HORIZONTAL_BARS;
        }
        String gbAreaCode = sysDepartParamService.getGbOrgInfo(orgCode);
        if (!ObjectUtils.isEmpty(gbAreaCode)) {
            areaCode = gbAreaCode.substring(0, 6);
        } else {
            if (orgCode.contains(Constant.STRING_UNDERLINE)) {
                //areaCode = orgCode.substring(0, orgCode.indexOf(Constant.STRING_UNDERLINE));
                areaCode = orgCode.substring(0, 6);
            }
        }
        String partyId = partyInfo.getPartyId();
        /*
            如果当事人id为空，则说明是单当事人/多当事人合并处罚，
            则caseId作为 punishBaseInfoCode，
            否则取当事人id作为 punishBaseInfoCode
         */
        String uid = partyId;
        //是否是多当事人分别处罚
        boolean isMultiplePartiesAndPartPunish = !ObjectUtils.isEmpty(partyId)?true:false;
        if(!isMultiplePartiesAndPartPunish){
            uid = caseId;
        }

        baseInfo.put("recordUniqueIdentity", uid);
        //案件编号
        baseInfo.put("punishCaseCode", caseNumber);
        baseInfo.put("punishActionName", caseMainInfoVo.getCaseName());
        baseInfo.put("implementInstitution", caseMainInfoVo.getCaseOrgName());
        baseInfo.put("implementInstitutionCode", caseMainInfoVo.getUniscid());
        //传带下划线的orgCode会导致无法公示，而该orgCode是易和的组织编码的含义，这个还需要配置（但是目前浙江政务网对这块没有特殊要求）
        //省司法厅的案件单独拿到易和的组织机构编码进行上报 330000000000_11330000002482154N 001003011
        if("330000000000_11330000002482154N".equals(orgCode)){
            baseInfo.put("orgCode", "001003011");
        }else if("330000000000_11330000002482904Y".equals(orgCode)){//省经信厅,001003084
            baseInfo.put("orgCode", "001003084");
        }else if("330000000000_11330000002482170C".equals(orgCode)){//省财政厅,001003012
            baseInfo.put("orgCode", "001003012");
        }else {
            baseInfo.put("orgCode", areaCode);
        }

        baseInfo.put("adminiDivisionCode", areaCode);
        // FIXME: 2022/3/31 目前写死"否"
        baseInfo.put("isEntrust", YesOrNoEnum.NO.getCode());
        // 受委托时此项信息必填
        //map.put("entrustDeptName","");
        //map.put("entrustDeptCode","");
        String caseTypeCode = Constant.STRING_HORIZONTAL_BARS;
        /*
        系统内部：
        1-简易程序/2-一般程序/3-快速办理
        数据上报规则：
        01-简易程序/02-一般程序
         */
        if (CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseType)) {
            caseTypeCode = "01";
        } else if (CaseTypeEnum.NORMAL_PROCEDURE.getCode().equals(caseType)) {
            caseTypeCode = "02";
        } else if (CaseTypeEnum.SIMPLE_QUICK.getCode().equals(caseType)) {
            caseTypeCode = "03";
        }
        baseInfo.put("caseProcessType", caseTypeCode);
        /*
        系统内部：
        机构检测报告
        社会举报
        上级行政机关交办
        下级行政机关报请
        有关部门移送
        非现场执法
        巡查中发现
        20221014 同步业务，新增"其他"
        20221019前？ 同步业务，新增"在行政检查中发现"

        数据上报规则：
        01=在行政检查中发现,
        02=机构检测报告,
        03=社会举报,
        04=上级行政机关交办,
        05=下级行政机构报请,
        06=有关部门移送,
        07=非现场执法
        08=巡查中发现

        99=其他

         */
        String caseSource = caseMainInfoVo.getCaseSource();
        // 2022/3/31 目前系统配置项中无"在行政检查中发现"项，默认这项，有对应值取对应值
        // 2022/9/19 发现系统配置项中新增了"在行政检查中发现"项，需要特殊传入检查编号信息
        String caseSourceCode = "";
        if (CaseSourceEnum.CASE_SOURCE_JGJCBG.getDes().equals(caseSource)) {
            caseSourceCode = "02";
        } else if (CaseSourceEnum.CASE_SOURCE_SHJB.getDes().equals(caseSource)) {
            caseSourceCode = "03";
        } else if (CaseSourceEnum.CASE_SOURCE_SJXZJGJB.getDes().equals(caseSource)) {
            caseSourceCode = "04";
        } else if (CaseSourceEnum.CASE_SOURCE_XJXZJGBQ.getDes().equals(caseSource)) {
            caseSourceCode = "05";
        } else if (CaseSourceEnum.CASE_SOURCE_YGBMYS.getDes().equals(caseSource)) {
            caseSourceCode = "06";
        } else if (CaseSourceEnum.CASE_SOURCE_FXCZF.getDes().equals(caseSource)) {
            caseSourceCode = "07";
        } else if (CaseSourceEnum.CASE_SOURCE_XCZFX.getDes().equals(caseSource)) {
            caseSourceCode = "08";
        } else if (CaseSourceEnum.CASE_SOURCE_QT.getDes().equals(caseSource)  || "其它".equals(caseSource)) {
            caseSourceCode = "99";
        } else if (CaseSourceEnum.CASE_SOURCE_ZXZJCZFX.getDes().equals(caseSource)) {
            caseSourceCode = "01";
        }
        if (ObjectUtils.isEmpty(caseSourceCode)) {
            throw new BusinessException("未匹配到案件来源信息");
        }
        baseInfo.put("caseSourceType", caseSourceCode);
        //日期格式测试后，再按需调整
        baseInfo.put("caseSourceDate", caseHappenTime + "");
        //检查案件编号
        if (CaseSourceEnum.CASE_SOURCE_ZXZJCZFX.getDes().equals(caseSource)) {
            //获取检查案件编号
            CaseSourceRegisterDetailInfo detailInfo = caseSourceRegisterDetailInfoService.getCaseSourceRegisterDetailInfoByCaseSourceId(caseId);
            if(CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseType)){
                detailInfo = caseSourceRegisterDetailInfoService.getCaseSourceRegisterDetailInfoByCaseSourceId(caseMainInfoVo.getDataSourceServiceId());
            }
            if (ObjectUtils.isEmpty(detailInfo)) {
                throw new BusinessException("未找到检查相关信息");
            } else {
                baseInfo.put("checkCaseCode", detailInfo.getCheckTaskId() + Constant.STRING_HORIZONTAL_BARS + detailInfo.getCheckTaskNumber());
            }
        }
        //移送部门信息
        //简易处罚没有简易处罚相关概念
        if ("06".equals(caseSourceCode)) {
            String transferUnitName = caseMainDetailInfo.getTransferUnit();
            String transferUnitUniscid = caseMainDetailInfo.getTransferUnitUniscid();
            baseInfo.put("deportationDeptName", transferUnitName);
            baseInfo.put("deportationDeptCode", transferUnitUniscid);
        }
        /*
        当事人类型：
        系统内部：
            个人
            法人
        数据上报规则：
            01	公民
            02	法人
            03	其他组织
            04	个体工商户
         */
        String casePartiesReasonType = caseMainInfoVo.getCasePartiesReasonType();
        String handleType = caseMainInfoVo.getHandleType();
        //默认单位
        String partyTypeCode;
        //证件类型
        String certType;
        //证件号码
        String certNumber = partyInfo.getPartyIdentityCode();
        //联系电话
        String telNumber = partyInfo.getContactPhone();
        String registerAddress = "";
        String businessAddress = "";

        String partyInfoType = partyInfo.getPartyType();
        if(PartyTypeEnum.PERSON.getCode().equals(partyInfoType)){
            partyTypeCode = "01";
            certType = CertTypeDataReportEnum.getReflectCodeByCode(partyInfo.getPartyIdentityType());
        } else {
            //单位
            certType = "001";
            String legalCertType = CertTypeDataReportEnum.getReflectCodeByCode(partyInfo.getPartyIdentityType());
            String entType = partyInfo.getEntType();
            registerAddress = partyInfo.getAddress();
            businessAddress = partyInfo.getAddress();
            //法定代表人证件类型
            baseInfo.put("legalRepresentativeType", legalCertType);
            //法定代表人姓名
            baseInfo.put("legalRepresentative", partyInfo.getLegalName());
            //法定代表人证件号码
            baseInfo.put("legalRepresentativeIdcard", partyInfo.getLegalCertNo());

            /*
                项目内枚举：单位类型(1:法人 2:个体工商户 3:其他组织)
                数据上报枚举：01公民/02法人/03其他组织/04个体工商户
             */
            if(EnterTypeEnum.PRIVATELY_BUSINESS.getCode().equals(entType)){
                partyTypeCode = "04";
            } else if(EnterTypeEnum.OTHER_ORG.getCode().equals(entType)){
                partyTypeCode = "03";
                // 证件类型也改成其他组织
                certType = "099";
            } else {
                partyTypeCode = "02";
            }
        }
        String partyName = partyInfo.getPartyName();
        if(PartiesReasonTypeEnum.MULTIPLE_PARTIES.getCode().equals(casePartiesReasonType)
                && HandleTypeEnum.MERGE_PUNISH.getCode().equals(handleType)){
            //多当事人合并处罚时名字+"等"
            partyName += "等";
        }
        //当事人类型
        baseInfo.put("administrativeCpType", partyTypeCode);
        //当事人名称
        baseInfo.put("administrativeCpName", partyName);
        /*
        当事人证件类型：
        系统内部：
            个人：
                身份证
                。。。
            法人：
                社会统一信用代码
        数据上报规则：
            001	统一社会信用代码
            099	其他法人或其他组织有效证件号码
            111	居民身份证
            112	临时居民身份证
            113	户口簿
            114	中国人民解放军军官证
            115	中国人民武装警察部队警官证
            117	出生医学证明
            118	中国人民解放军士兵证
            119	中国人民武装警察部队士兵证
            120	中国人民解放军文职人员证
            122	中国人民武装警察部队文职人员证
            154	居住证
            411	外交护照
            412	公务护照
            413	公务普通护照
            414	普通护照
            415	旅行证
            511	台湾居民来往大陆通行证港
            516	澳居民来往内地通行证
         */

        //当事人证件类型
        baseInfo.put("administrativeCpCertType", certType);
        //当事人证件号码
        baseInfo.put("administrativeCpCertCode", certNumber);
        //当事人联系电话
        baseInfo.put("administrativeCpTel", telNumber);

          /*map.put("areaCodeLive","");
        map.put("areaNameLive","");
        map.put("addressLive","");
        map.put("areaCodeRegisterd","");
        map.put("areaNameRegisterd","");

        map.put("areaCodeOperating","");
        map.put("areaNameOperating","");
        */
        baseInfo.put("addressRegisterd", registerAddress);
        baseInfo.put("addressOperating", businessAddress);
        //获取办案人员信息
        List<CaseHandlePersonRecordVo> caseHandlePersonRecordList = caseHandlePersonRecordService.getCaseHandlePersonRecordListByCaseId(caseId);
        String handlePersonNameStr = "";
        String handlePersonCertStr = "";
        for (CaseHandlePersonRecordVo p : caseHandlePersonRecordList) {
            handlePersonNameStr += p.getHandlePersonName() + ",";
            String lawEnforcementCert = p.getLawEnforcementCert();
            String tmpCertStr;
            if (ObjectUtils.isEmpty(lawEnforcementCert)) {
                tmpCertStr = "-";
            } else {
                if (lawEnforcementCert.contains(Constant.STRING_COMMA)) {
                    tmpCertStr = lawEnforcementCert.substring(0, lawEnforcementCert.indexOf(Constant.STRING_COMMA));
                } else {
                    tmpCertStr = lawEnforcementCert;
                }
            }
            handlePersonCertStr += tmpCertStr + ",";
        }
        if (!ObjectUtils.isEmpty(handlePersonNameStr) && handlePersonNameStr.endsWith(Constant.STRING_COMMA)) {
            handlePersonNameStr = handlePersonNameStr.substring(0, handlePersonNameStr.length() - 1);
        }
        if (!ObjectUtils.isEmpty(handlePersonCertStr) && handlePersonCertStr.endsWith(Constant.STRING_COMMA)) {
            handlePersonCertStr = handlePersonCertStr.substring(0, handlePersonCertStr.length() - 1);
        }
        baseInfo.put("punishPersonnelName", handlePersonNameStr);
        baseInfo.put("punishPersonnelCode", handlePersonCertStr);
        String caseDesc = caseMainDetailInfo.getCaseConciseCondition();
        baseInfo.put("caseDesc",ObjectUtils.isEmpty(caseDesc)?Constant.STRING_HORIZONTAL_BARS:caseDesc);
        //行政行为码
        baseInfo.put("punishActionCode", caseMainInfoVo.getCaseActsCode());
        baseInfo.put("barCodeUrl", caseMainInfoVo.getCaseBarCodeUrl());
        baseInfo.put("qrCodeUrl", caseMainInfoVo.getCaseQrCodeUrl());
        //应急案由
        if(TerritoryCodeEnum.YJGL.getCode().equals(caseMainInfoVo.getCaseTerritoryCode()) && StrUtil.isNotEmpty(caseMainDetailInfo.getCaseEmergencyReasonContent())){
            String caseEmergencyReasonContent = caseMainDetailInfo.getCaseEmergencyReasonContent();
            List<CaseEmergencyReasonInfoDto> list = JSON.parseArray(caseEmergencyReasonContent, CaseEmergencyReasonInfoDto.class);
            List<String> reasonNameList = CollUtil.newArrayList();
            list.forEach( u -> reasonNameList.add(u.getEmergencyReasonName()));
            baseInfo.put("punishAy", CollUtil.join(reasonNameList, "&"));
        }


        /*非必填
        map.put("isDeported","");
        map.put("deportTime","");*/
        if (!ObjectUtils.isEmpty(registerTime)) {
            baseInfo.put("isFiling", Constant.STRING_1);
        } else {
            baseInfo.put("isFiling", Constant.STRING_0);
        }
        baseInfo.put("sourceDeptCode", sourceDeptCode);

        //获取caseId+reportDataType+isTestData 对应记录
        CaseDataReportRecordQueryDto queryDto = new CaseDataReportRecordQueryDto();
        queryDto.setCaseId(caseId);
        queryDto.setReportDataType(reportDataType);
        queryDto.setIsTestData(YesOrNoEnum.YES.getCode());
        queryDto.setPartyId(partyId);
        //默认测试数据1
        String envFlag = Constant.STRING_1;
        if (SpringContextUtil.checkIsPrdProfile()) {
            queryDto.setIsTestData(YesOrNoEnum.NO.getCode());
            envFlag = Constant.STRING_0;
        }
        List<CaseDataReportRecordVo> list = caseDataReportRecordService.getCaseDataReportRecord(queryDto);
        //基础信息数据上报类型（I-新增/U-更新）

        String isBasicInfoExists = "I";
        //事项信息数据上报类型（I-新增/U-更新）
        String isItemInfoExists = "I";

        String reportActionType = "I";
        if (!ObjectUtils.isEmpty(list) && list.size() > 0) {
            CaseDataReportRecordVo latestRecord = list.get(Constant.INTEGER_0);
            String latestReportResult = latestRecord.getReportResult();
            if (!Constant.STRING_0.equals(latestReportResult)) {
                //失败
                String oriActionType = latestRecord.getReportActionType();
                reportActionType = "U".equals(oriActionType) ? oriActionType : "I";
                /*
                    如果存在未完成且 reportFailReason like '该条数据已存在',则将optType调整为U;
                    -[基础信息]该条数据已经存在
                    -[事项信息]该条数据已经存在
                 */
                String reportFailReason = latestRecord.getReportFailReason();
                if(!ObjectUtils.isEmpty(reportFailReason)){
                    if(reportFailReason.contains("[基础信息]该条数据已经存在")){
                        isBasicInfoExists = "U";
                    } else if(reportFailReason.contains("[事项信息]该条数据已经存在")){
                        isItemInfoExists = "U";
                    }
                }

            } else {
                reportActionType = "U";
            }
        }
        if (isUpdateReReport) {
            reportActionType = "U";
        }
        String totalOptType = "I";
        if ("U".equals(isBasicInfoExists) || "U".equals(isItemInfoExists)) {
            totalOptType = "U";
        }
        //判断是否为更新
        CaseDataReportStageInfoQueryDto query = new CaseDataReportStageInfoQueryDto();
        query.setReportStageTag(ReportDataTypeEnum.BASE.getCode());
        query.setIsFinishReport(YesOrNoEnum.YES.getCode());
        query.setPartyId(partyId);
        query.setCaseId(caseId);
        List<CaseDataReportStageInfoVo> listStage = caseDataReportStageInfoService.getCaseDataReportStageInfoList(query);
        if ("I".equals(totalOptType) && listStage.size() > 0) {
            totalOptType = "U";
        }
        baseInfo.put("optType", !ObjectUtils.isEmpty(optType) ? optType :totalOptType);
        //非必填
        if (CaseTypeEnum.SIMPLE_PROCEDURE.getCode().equals(caseType)) {
            baseInfo.put("isHandCase", "1");
        }
        //应急管理加是否工商专项(0-否/1-是)
        if(TerritoryCodeEnum.YJGL.getCode().equals(caseMainInfoVo.getCaseTerritoryCode())){
            baseInfo.put("industryTrade", Constant.STRING_1.equals(caseMainDetailInfo.getIsIndustrialTradeSpecial()) ? Constant.STRING_0 : Constant.STRING_1);
        }
        //违法时间
        baseInfo.put("illegalTime", caseHappenTime + "");
        returnInfo.put("baseInfo", baseInfo);

        JSONArray itemInfo = collectItemInfo(caseId, (totalOptType), envFlag, sourceDeptCode, partyId);
        JSONObject filingInfo = new JSONObject();

        //构造立案文书号/立案批准人
        filingInfo.put("recordUniqueIdentity", BaseUtil.createUid());

        filingInfo.put("punishBaseInfoCode", uid);
        //立案批准日期
        filingInfo.put("filingDate", registerTime+"");
        //立案批准人[非必填]
        //filingInfo.put("filingPerson","");
        //立案文书号[非必填]
        filingInfo.put("filingCode", caseNumber);

        filingInfo.put("optType", totalOptType);
        filingInfo.put("envFlag", envFlag);
        filingInfo.put("sourceDeptCode", sourceDeptCode);

        returnInfo.put("superviseItemInfoList", itemInfo);
        returnInfo.put("filingInfo", filingInfo);
        //到dataReport时清空该键值
        returnInfo.put("reportActionType", !ObjectUtils.isEmpty(optType)?optType:reportActionType);
        returnInfo.put("envFlag", envFlag);

        log.info("reportDataCollect end...result-returnInfo:{}", returnInfo);
        return returnInfo;
    }

    /**
     * 描述：行政处罚事项信息(案由相关信息)
     *
     * @param caseId         案件id
     * @param optType        操作类型
     * @param envFlag        是否为测试数据 0-否（正式）/1-是（测试）
     * @param sourceDeptCode 来源厅局编码
     * @param partyId        当事人id
     * @return JSONArray 处罚是想信息
     * @author xiangyuyu
     * @date 2022-03-31 18:06
     */
    private JSONArray collectItemInfo(String caseId, String optType, String envFlag, String sourceDeptCode,String partyId) {
        log.info("collectItemInfo start...param-caseId:{},optType:{},envFlag:{},sourceDeptCode:{}",
                caseId, optType, envFlag, sourceDeptCode);
        JSONArray jsonArray = new JSONArray();
        CaseReasonMainRecordQueryDto queryDto = new CaseReasonMainRecordQueryDto();
        queryDto.setCaseId(caseId);
        List<CaseReasonMainRecordVo> caseReasonMainRecordList = caseReasonMainRecordService.getCaseReasonRecordList(queryDto);
        /*
            如果当事人id为空，则说明是单当事人/多当事人合并处罚，
            则caseId作为 punishBaseInfoCode，
            否则取当事人id作为 punishBaseInfoCode
         */
        String uid = partyId;
        //是否是多当事人分别处罚
        boolean isMultiplePartiesAndPartPunish = !ObjectUtils.isEmpty(partyId)?true:false;
        if(!isMultiplePartiesAndPartPunish){
            uid = caseId;
        }
        CaseMainInfoVo caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
        if(TerritoryCodeEnum.RLSB.getCode().equals(caseMainInfo.getCaseTerritoryCode()) && ObjectUtil.isEmpty(caseReasonMainRecordList)){
            CaseMainDetailInfo caseMainDetailInfo = caseMainDetailInfoService.getCaseMainDetailByCaseId(caseId);
            if(StrUtil.isNotEmpty(caseMainDetailInfo.getPersonReasonId()) && StrUtil.isNotEmpty(caseMainDetailInfo.getPersonReasonName())){
                //案由名称
                String[] reasonNameArr = caseMainDetailInfo.getPersonReasonName().split(Constant.STRING_COMMA);
                //code
                List<PersonReasonIds> list = JSON.parseArray(caseMainDetailInfo.getPersonReasonId(), PersonReasonIds.class);
                for(int i=0;i<list.size();i++){
                    PersonReasonIds personReasonIds = list.get(i);
                    String caseReasonCode = personReasonIds.getCaseReasonIds().get(Constant.INTEGER_1);
                    String caseReasonName = reasonNameArr[i];
                    JSONObject item = new JSONObject();
                    item.put("recordUniqueIdentity", BaseUtil.createUid());
                    item.put("punishBaseInfoCode", uid);
                    item.put("superviseItemCode", caseReasonCode);
                    item.put("superviseItemName", caseReasonName);
                    item.put("optType", optType);
                    item.put("envFlag", envFlag);
                    item.put("sourceDeptCode", sourceDeptCode);
                    jsonArray.add(item);
                }
                return jsonArray;
            }
        }
        for (CaseReasonMainRecordVo record : caseReasonMainRecordList) {
            JSONObject item = new JSONObject();
            item.put("recordUniqueIdentity", BaseUtil.createUid());
            item.put("punishBaseInfoCode", uid);
            item.put("superviseItemCode", record.getCaseReasonCode());
            item.put("superviseItemName", record.getCaseReasonName());
            item.put("optType", optType);
            item.put("envFlag", envFlag);
            item.put("sourceDeptCode", sourceDeptCode);
            jsonArray.add(item);
        }
        // FIXME: 2022/3/31 待校验日志输出的合理性
        log.info("collectItemInfo end...result:{}", jsonArray);
        return jsonArray;
    }

    public static void main(String[] args) {
        String str = "[{\"caseReasonIds\":[\"70d460d53e39685ca5b3c61a6d9e5299\",\"EF0E913D252E4A92BB54EF7FAAC61599\"]},{\"caseReasonIds\":[\"70d460d53e39685ca5b3c61a6d9e5299\",\"BAF1CF84BA5043188BB386CEEDE2BF52\"]},{\"caseReasonIds\":[\"ebfee705b36fc304d5cf745f49a1921e\",\"FACB3CD1F69F41C283D15ACB8D48A100\"]}]";
        String str1 = "违反劳务派遣规定,拖欠克扣工资,骗取社会保险待遇";
        //案由名称
        String[] reasonNameArr = str1.split(Constant.STRING_COMMA);
        //code
        List<PersonReasonIds> list = JSON.parseArray(str, PersonReasonIds.class);
        for(int i=0;i<list.size();i++){
            PersonReasonIds personReasonIds = list.get(i);
            String caseReasonCode = personReasonIds.getCaseReasonIds().get(Constant.INTEGER_1);
            String caseReasonName = reasonNameArr[i];
            System.out.println(caseReasonCode + ", " + caseReasonName);
        }
    }

    /**
     * 描述：批量案件重新数据上报（U）
     *
     * @return {@link Result <String>} 上报失败案件id列表
     * @author xiangyuyu
     * @date 2022-06-13 18:52
     */
    @Override
    public List<String> batchCaseReportAgain() {
        return null;
    }


    /**
     * 描述：数据上报-base（重推-U）
     *
     * @param caseId 案件id
     * @param partyInfo    {@link CasePartiesInfoVo} 当事人信息
     * @param caseMainInfo {@link CaseMainInfoVo} 案件主体信息
     * @return {@link Result <String>} 上报结果
     * @author xiangyuyu
     * @date 2022-04-21 19:13
     */
    @Override
    public Result<String> singleCaseReportAgain(String caseId, CasePartiesInfoVo partyInfo, CaseMainInfoVo caseMainInfo) {
        log.info("singleCaseReportAgain start... caseId:{}", caseId);
        if(ObjectUtils.isEmpty(partyInfo)){
            partyInfo = new CasePartiesInfoVo();
        }
        String partyId = partyInfo.getPartyId();
        try {
            if (caseDataReportRecordService.getIsAllowDataReport(caseId)) {
                String errorMsg;
                if(ObjectUtils.isEmpty(caseMainInfo)){
                    //根据案件id查询案件信息
                    caseMainInfo = caseMainInfoService.getCaseMainInfo(caseId);
                }
                String uri = BASE_HTTP;
                String reportDataType = ReportDataTypeEnum.BASE.getCode();
                JSONObject reportData = reportDataCollect(caseMainInfo, reportDataType, false, partyInfo, CaseDataReportOptTypeEnum.U.getCode());
                Map<String, String> params = new HashMap<>(2);
                params.put("reportActionType", reportData.getString("reportActionType"));
                params.put("envFlag", reportData.getString("envFlag"));
                params.put("baseInfo", reportData.toJSONString());
                errorMsg = caseDataReportRecordService.dataReport(uri, reportDataType, params, caseMainInfo);

                log.info("dataReportBaseRe end");
                if (ObjectUtils.isEmpty(errorMsg)) {
                    caseDataReportStageInfoService.dealAfterReport(caseId, true, ReportDataTypeEnum.BASE.getCode(), null,partyId);
                    return Result.success("上报成功");
                } else {
                    if (errorMsg.contains(Constant.STRING_RECORD_EXISTS)) {
                        caseDataReportStageInfoService.dealAfterReport(caseId, true, ReportDataTypeEnum.BASE.getCode(), errorMsg,partyId);
                    } else {
                        caseDataReportStageInfoService.dealAfterReport(caseId, false, ReportDataTypeEnum.BASE.getCode(), errorMsg,partyId);
                    }
                    return Result.error(errorMsg);
                }
            } else {
                String tmpMsg = "该部门是否允许上报数据按钮处于关闭状态,caseId:" + caseId;
                throw new BusinessException(tmpMsg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            caseDataReportStageInfoService.dealAfterReport(caseId, false, ReportDataTypeEnum.BASE.getCode(), e.getMessage(),partyId);
            return Result.error("singleCaseReportAgain catch exception：" + e.getMessage());
        }
    }
}
